package com.sgj.springcloud.lb;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author 沈国纪
 * @date 2021/5/16 11:03
 */
@Component
@Slf4j
public class MyLB implements LoadBalancer {

	private AtomicInteger atomicInteger = new AtomicInteger(0);

	/**
	 * 获取当前访问次数
	 * @return
	 */
	public final int getAndIncrement() {
		// 当前值
		int current;
		// 第几次请求
		int next;
		do {
			current = this.atomicInteger.get();
			// 2147483647 为 int 最大值，不能越界
			next = current >= 2147483647 ? 0 : current + 1;
			log.info("[MyLB][getAndIncrement] current:{}", current);
			log.info("[MyLB][getAndIncrement] next:{}", next);
			// 由于 compareAndSet(a, b) 方法时对比 a, b的值，如果 b 比 a 大，则返回 true，并将 b 的值赋给 a,反之则 a 的值不变，返回 false
			// 这里每次循环都必定是true，所以要给一个感叹号，每一次请求都返回一次
		} while(!this.atomicInteger.compareAndSet(current, next));
		log.info("[MyLB][getAndIncrement] nextFinal:{}", next);
		return next;
	}

	@Override
	public ServiceInstance instances(List<ServiceInstance> serviceInstances) {
		// 相当于获取服务器数组对应下标
		int index = getAndIncrement() % serviceInstances.size();
		return serviceInstances.get(index);
	}
}
